(function(global,factory){
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global = global || self, global.obj = factory());
}(this,function(){
    let Obj = {
        emptyObj(obj){
            let value = JSON.stringify(obj)
            return value == '{}' || value == '[]';
        }
        // 判断是否是NaN值。
        // NaN的特点：自己不等于自己
        ,isReallyNaN(value) {
          return value !== value;
        }
        ,exist(value, options = { zero: false, ltzero: true }) {
            const { zero, ltzero } = options;

            const conditions = [
                value === null,
                value === undefined,
                Number.isNaN(value),
                [Infinity, -Infinity].includes(value),
                /^\s*$/.test(value),
                typeof value === 'object' && Object.keys(value).length === 0,
                !zero && value === 0,
                !ltzero && +value < 0
            ];
            /* 针对多个 || 使用some方法改进*/ 
            const flag = conditions.some(condition => condition);
          
            return !flag;
        }
          
        //回到顶部
        ,toTop(){
            let root = document.documentElement.clientHeight && document.documentElement || document.body;
            root.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
        }
        ,isType(type){
            type = type.charAt(0).toUpperCase()+type.substring(1);
            return function(obj){
                return Object.prototype.toString.call(obj) == `[object ${type}]`;
            }
        }
        ,toStr(obj){
            return Object.prototype.toString.call(obj)
        }
        //深拷贝
        ,merge(target, ...sources) {
            for (const source of sources) {
              for (const [key, value] of Object.entries(source)) {
                if (typeof value === 'object' && value !== null) {
                  target[key] = merge(target[key] ?? (Array.isArray(value) ? [] : {}), value);
                } else {
                  target[key] = value;
                }
              }
            }
            return target;
        }   
        // 是否是引用数据类型
        ,isRefType(value) {
            return typeof value === 'object' && value !== null;
        }
        ,deepEqual(obj1, obj2) {
            // 如果两个对象引用同一个内存地址，则它们相等
            if (obj1 === obj2) {
                return true;
            }
            if(!isRefType(obj1) || !isRefType(obj2)){
                return false;
            }
            // 获取两个对象所有属性名
            const keys1 = Object.keys(obj1);
            const keys2 = Object.keys(obj2);
            // 如果属性名数量不同，则两个对象不相等
            if (keys1.length !== keys2.length) {
                return false;
            }
            // 迭代所有属性，逐一比较它们的值
            for (let i = 0; i < keys1.length; i++) {
                const key = keys1[i];
                // 如果obj2不存在该属性或者属性值不相等，则两个对象不相等
                if (!obj2.hasOwnProperty(key) || !deepEqual(obj1[key], obj2[key])) {
                    return false;
                }
            }
            // 所有属性值相等，则两个对象相等
            return true;
        }
        ,equals(a, b, epsilon = 1e-10, memo = new WeakMap()) {
            if (typeof a !== typeof b) {
              return false;
            }
            if (a === b) {
              // 包括 undefined、null、数值、字符串、布尔等基本数据类型
              return true;
            }
            if (typeof a === 'number' && typeof b === 'number' &&
                !Number.isNaN(a) && !Number.isNaN(b)) {
                // 数值类型相等有两种可能：完全相等或近似相等
                return Math.abs(a - b) < epsilon;
            }
            if (a instanceof RegExp && b instanceof RegExp) {
              // 正则表达式可以使用 toString() 方法转为字符串后比较
              return a.toString() === b.toString();
            }
            if (a instanceof Date && b instanceof Date) {
              // 日期可以使用 getTime() 方法转为时间戳后比较
              return a.getTime() === b.getTime();
            }
            if (Array.isArray(a) && Array.isArray(b)) {
              // 数组需要逐一比较元素
              if (a.length !== b.length) {
                return false;
              }
              for (let i = 0; i < a.length; i++) {
                if (!equals(a[i], b[i], epsilon, memo)) {
                  return false;
                }
              }
              return true;
            }
            if (a && b && typeof a === 'object' && typeof b === 'object') {
              // 对象需要逐一比较属性
              // 确保不会出现循环引用的情况
              if (memo.has(a) && memo.get(a) === b) {
                return true;
              }
              memo.set(a, b);
              let keysA = Object.keys(a).sort();
              let keysB = Object.keys(b).sort();
              if (!equals(keysA, keysB)) {
                return false;
              }
              for (let i = 0; i < keysA.length; i++) {
                let key = keysA[i];
                if (!equals(a[key], b[key], epsilon, memo)) {
                  return false;
                }
              }
              return true;
            }
            return false;
        }

    }

    Obj.isObject = Obj.isType('object')

    return Obj;
}));

